import { LocationStateType } from '@/components/AuthRoute';
import store from '@/store';
import { Toast } from 'antd-mobile';
import axios from 'axios';
import history from './history';
import { getToken, removeToken, setToken } from './storage';

// 请求基础地址
export const baseURL = 'http://geek.itheima.net';

const request = axios.create({
  baseURL,
  timeout: 5000, //配置请求超时
});

// 请求拦截器
request.interceptors.request.use(
  (config) => {
    // 设置请求token
    const { token } = getToken();
    //  config.headers!.Authorization = `Bearer ${token}`;
    if (token && config.headers) {
      config.headers.Authorization = `Bearer ${token}`;
    }

    // console.log('请求拦截器', config);
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// 响应拦截器
request.interceptors.response.use(
  (response) => {
    // console.log('响应拦截器', response);
    return response.data;
  },
  async (error) => {
    // console.dir(error);

    // 网络错误提示用户
    if (!error.response) {
      Toast.show({ content: '网络出错啦!' });
      //修复逻辑漏洞
      return Promise.reject(error);
    }
    // 错误信息非401
    if (error.response.status !== 401) {
      Toast.show({ content: error.response.data.message });
    } else {
      // 401 (token失效)
      // 无感刷新
      const refresh_token = getToken().refresh_token;
      // 当token失效时,通过refresh_token,重新获取token
      if (refresh_token) {
        // try,catch捕获错误信息
        try {
          let res = await axios({
            url: baseURL + '/v1_0/authorizations',
            method: 'put',
            headers: {
              Authorization: `Bearer ${refresh_token}`,
              'Content-Type': 'application/x-www-form-urlencoded',
            },
          });
          // console.log(res.data.data.token);

          // 实现无感刷新
          // 保存token到reducer和缓存中
          const auth = { token: res.data.data.token, refresh_token };
          // 保存到reducer
          store.dispatch({ type: 'user/saveAuth', payload: auth });
          // 保存到缓存
          setToken(auth);
          // 请求原来的请求  , error.config就是报错前的请求信息
          // request(error.config);重新发送请求
          return request(error.config);
        } catch (error) {
          // 清除token
          removeToken();
          // 清除reducer的token
          store.dispatch({ type: 'user/saveAuth', payload: {} as any });

          // push接收第二个参数state对象,登录后重定向到跳转前的页面
          history.push('/login', {
            from: history.location.pathname,
          } as LocationStateType);
        }
      } else {
        // 删除Token
        removeToken();

        // push接收第二个参数state对象,登录后重定向到跳转前的页面
        history.push('/login', {
          from: history.location.pathname,
        } as LocationStateType);
      }
      Toast.show({ content: '登录超时,请重新登录!' });
    }

    return Promise.reject(error);
  }
);

export default request;
